package com.hjy.product.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.hjy.common.to.SpuReductionTo;
import com.hjy.common.to.es.SkuEsModel;
import com.hjy.common.utils.PageUtils;
import com.hjy.common.utils.Query;
import com.hjy.common.utils.R;
import com.hjy.product.dao.*;
import com.hjy.product.entity.*;
import com.hjy.product.feign.SearchFeignService;
import com.hjy.product.feign.WareFeignService;
import com.hjy.product.feign.couponFeignClient;
import com.hjy.product.service.SpuInfoDescService;
import com.hjy.product.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.sql.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.hjy.product.service.SpuInfoService;
import org.springframework.transaction.annotation.Transactional;


@Service("spuInfoService")
@Slf4j
public class SpuInfoServiceImpl extends ServiceImpl<SpuInfoDao, SpuInfoEntity> implements SpuInfoService {

    @Autowired
    private SpuInfoDescService spuInfoDescService;

    @Autowired
    private SpuImagesDao spuImagesDao;

    @Autowired
    private AttrDao attrDao;

    @Autowired
    private SkuInfoDao skuInfoDao;

    @Autowired
    private SkuImagesDao skuImagesDao;
    @Autowired
    private BrandDao brandDao;

    @Autowired
    private CategoryDao categoryDao;

    @Autowired
    private SkuSaleAttrValueDao skuSaleAttrValueDao;
    @Autowired
    private couponFeignClient couponFeignClient;

    @Autowired
    private ProductAttrValueDao productAttrValueDao;

    @Autowired
    private WareFeignService wareFeignService;

    @Autowired
    private SearchFeignService searchFeignService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<SpuInfoEntity> wrapper = new QueryWrapper<>();
        // 构造条件
        /*
           key: '华为',//检索关键字
           catelogId: 6,//三级分类id
           brandId: 1,//品牌id
           status: 0,//商品状态
         */
        String key = (String) params.get("key");
        if(StrUtil.isNotBlank(key)) {
            wrapper.and((wrapper1) -> {
                wrapper1.eq("id",key).or().like("spu_name",key);
            });
        }
        String catelogId = (String) params.get("catelogId");
        if(StrUtil.isNotBlank(catelogId)) {
            wrapper.eq("catalog_id",catelogId);
        }
        String brandId = (String) params.get("brandId");
        if(StrUtil.isNotBlank(brandId)) {
            wrapper.eq("brand_id",brandId);
        }
        String status = (String) params.get("status");
        if(StrUtil.isNotBlank(status)) {
            wrapper.eq("publish_status",status);
        }
        IPage<SpuInfoEntity> page = this.page(
                new Query<SpuInfoEntity>().getPage(params),
                wrapper
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void saveSpuInfo(spuSavavo savavo) {
        // 1, 保存 spu 基本信息 pms_spu_info
        SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
        BeanUtil.copyProperties(savavo, spuInfoEntity);
        spuInfoEntity.setCreateTime(new Date(System.currentTimeMillis()));
        spuInfoEntity.setUpdateTime(new Date(System.currentTimeMillis()));
        baseMapper.insert(spuInfoEntity);
        // 2, 保存spu描述图片 pms_spu_info_desc
        List<String> decript = savavo.getDecript();
        if (CollUtil.isNotEmpty(decript)) {
            SpuInfoDescEntity spuInfoDescEntity = new SpuInfoDescEntity();
            spuInfoDescEntity.setDecript(StrUtil.join(",", decript));
            spuInfoDescEntity.setSpuId(spuInfoEntity.getId());

            spuInfoDescService.save(spuInfoDescEntity);
        }

        // 3, 保存spu图片集  pms_spu_images
        List<String> images = savavo.getImages();
        if (CollUtil.isNotEmpty(images)) {
            images.forEach(s -> {
                SpuImagesEntity spuImagesEntity = new SpuImagesEntity();
                spuImagesEntity.setImgUrl(s);
                spuImagesEntity.setSpuId(spuInfoEntity.getId());
                spuImagesDao.insert(spuImagesEntity);
            });
        }


        // 4, 保存spu规格参数 pms_product_attr_value
        List<BaseAttrs> baseAttrs = savavo.getBaseAttrs();
        if (CollUtil.isNotEmpty(baseAttrs)) {
            baseAttrs.forEach(baseAttrs1 -> {
                ProductAttrValueEntity productAttrValueEntity = new ProductAttrValueEntity();
                productAttrValueEntity.setSpuId(spuInfoEntity.getId());
                productAttrValueEntity.setAttrId(baseAttrs1.getAttrId());
                // 先获取 Attr 对象
                AttrEntity attrEntity = attrDao.selectById(baseAttrs1.getAttrId());
                if (ObjectUtil.isNotNull(attrEntity)) {
                    productAttrValueEntity.setAttrName(attrEntity.getAttrName());
                }
                productAttrValueEntity.setAttrValue(baseAttrs1.getAttrValues());
                productAttrValueEntity.setAttrSort(0);
                productAttrValueEntity.setQuickShow(baseAttrs1.getShowDesc());
                // 保存
                productAttrValueDao.insert(productAttrValueEntity);
            });
        }

        // 5, 保存 spu 积分信息 sms_spu_bounds
        Bounds bounds = savavo.getBounds();
        if (bounds != null) {
            SpuBoundsVo spuBoundsVo = new SpuBoundsVo();
            BeanUtil.copyProperties(bounds, spuBoundsVo);
            spuBoundsVo.setSpuId(spuInfoEntity.getId());
            R r = couponFeignClient.save(spuBoundsVo);
            if (!r.getMessage().equals("success")) {
                log.info("couponFeignClient的save失败调用");
            }
        }
        // 6, 保存spu对应的所有sku信息
        //6,1 sku基本信息 pms_sku_info
        List<Skus> skus = savavo.getSkus();
        if (CollUtil.isNotEmpty(skus)) {
            skus.forEach(skus1 -> {
                SkuInfoEntity skuInfoEntity = new SkuInfoEntity();
                BeanUtil.copyProperties(skus1, skuInfoEntity);
                skuInfoEntity.setSkuDesc(skus1.getSkuSubtitle());
                // spuId
                skuInfoEntity.setSpuId(spuInfoEntity.getId());
                // skuDefaultImg
                List<Images> images1 = skus1.getImages();
                if (CollUtil.isNotEmpty(images1)) {
                    for (Images images2 : images1) {
                        if (images2.getDefaultImg() == 1) {
                            skuInfoEntity.setSkuDefaultImg(images2.getImgUrl());
                        }
                    }
                }
                // saleCount
                skuInfoEntity.setSaleCount(0L);
                //	private Long catalogId;
                skuInfoEntity.setCatalogId(spuInfoEntity.getCatalogId());
                //	private Long brandId;
                skuInfoEntity.setBrandId(spuInfoEntity.getBrandId());

                skuInfoDao.insert(skuInfoEntity);
                //6.2 sku图片信息 pms_sku_images
                if (CollUtil.isNotEmpty(images1)) {
                    for (Images images2 : images1) {
                        SkuImagesEntity skuImagesEntity = new SkuImagesEntity();
                        BeanUtil.copyProperties(images2, skuImagesEntity);
                        skuImagesEntity.setSkuId(skuInfoEntity.getSkuId());
                        skuImagesEntity.setImgSort(0);
                        // 如果getImgUrl没有值, 就跳过
                        if (StrUtil.isBlank(images2.getImgUrl())) {
                            continue;
                        }
                        skuImagesDao.insert(skuImagesEntity);
                    }
                }

                //6.3 sku销售属性信息 pms_sku_sale_attr_value
                List<Attr> attrs = skus1.getAttr();
                if (CollUtil.isNotEmpty(attrs)) {
                    attrs.forEach(attr -> {
                        SkuSaleAttrValueEntity skuSaleAttrValueEntity = new SkuSaleAttrValueEntity();
                        BeanUtil.copyProperties(attr, skuSaleAttrValueEntity);
                        skuSaleAttrValueEntity.setSkuId(skuInfoEntity.getSkuId());
                        skuSaleAttrValueEntity.setAttrSort(0);
                        skuSaleAttrValueDao.insert(skuSaleAttrValueEntity);
                    });
                }

                //5.4 sku优惠 满减等信息 sms_sku_ladder sms_sku_full_reduction
                SpuReductionTo spuReductionTo = new SpuReductionTo();
                BeanUtil.copyProperties(skus1, spuReductionTo);
                spuReductionTo.setSkuId(skuInfoEntity.getSkuId());
                if (spuReductionTo.getFullCount() > 0 && spuReductionTo.getFullPrice().compareTo(new BigDecimal(0)) > 0) {
                    R r = couponFeignClient.saveReduction(spuReductionTo);
                    if (!r.getMessage().equals("success")) {
                        log.error("couponFeignClient的saveReduction失败调用");
                    }
                }

            });
        }
    }
    // 商品上架
    @Override
    @Transactional
    public void up(Long spuId) {
        // 1. 首先通过 id 获取所有的 sku
        List<SkuInfoEntity> skuInfoList = skuInfoDao.selectList(new QueryWrapper<SkuInfoEntity>().eq("spu_id", spuId));

        // 查询出当前 sku 的所有可以被用来检索的规格属性
        List<ProductAttrValueEntity> productAttrValueEntityList = productAttrValueDao.selectList(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId));
        // 获取所有的 attrId
        List<Long> attrIds = productAttrValueEntityList.stream().map(ProductAttrValueEntity::getAttrId).collect(Collectors.toList());
        // 过滤掉不可以检索的属性
        QueryWrapper<AttrEntity> attrEntityQueryWrapper = new QueryWrapper<>();
        attrEntityQueryWrapper.and(attrEntityQueryWrapper1 -> {
            attrEntityQueryWrapper1.in("attr_id",attrIds).eq("search_type",1);
        });
        List<AttrEntity> list = attrDao.selectList(attrEntityQueryWrapper);
        // 获取到对应的属性
        List<Long> collect1 = list.stream().map(AttrEntity::getAttrId).collect(Collectors.toList());

        // 构造Attrs
        HashSet<Long> set = new HashSet<>(collect1);
        List<SkuEsModel.Attrs> collect2 = productAttrValueEntityList.stream().filter(productAttrValueEntity -> {
            return set.contains(productAttrValueEntity.getAttrId());
        }).map(productAttrValueEntity -> {
            SkuEsModel.Attrs attrs = new SkuEsModel.Attrs();
            BeanUtil.copyProperties(productAttrValueEntity, attrs);
            return attrs;
        }).collect(Collectors.toList());

        // 远程调用 ware 库存服务, 获取每一个 sku 的库存信息
        R skuHasStock = wareFeignService.getSkuHasStock(skuInfoList.stream().map(SkuInfoEntity::getSkuId).collect(Collectors.toList()));
        Map<Long, Boolean> mapStock = null;
        if (skuHasStock != null) {
            try {
                // 这里转换的 data 是一个 map 类型, map 中去值还是map
                Object data = skuHasStock.get("data");
                List<SkuHasStockVo> skuHasStockVos = JSONUtil.toList(JSONUtil.toJsonStr(data), SkuHasStockVo.class);
                mapStock = skuHasStockVos.stream().collect(Collectors.toMap(SkuHasStockVo::getSkuId, SkuHasStockVo::getHasStock));
            }catch (Exception e) {
                e.printStackTrace();
            }
        }

        // 2. 获取一个 es 的对象
        if (CollUtil.isNotEmpty(skuInfoList)) {
            Map<Long, Boolean> finalMapStock = mapStock;
            List<SkuEsModel> collect = skuInfoList.stream().map(sku -> {
                SkuEsModel skuEsModel = new SkuEsModel();
                BeanUtil.copyProperties(sku, skuEsModel);
                // 还有一些属性没有拷贝过来, 需要设置
                // skuPrice skuImg hasStock hotScore brandName brandImg catalogName attrs
                skuEsModel.setSkuPrice(sku.getPrice());
                skuEsModel.setSkuImg(sku.getSkuDefaultImg());
                // 设置 hasStock hotScore
                // hasStock 需要请求 gulimall-ware 库存服务
                skuEsModel.setHotScore(0L);
                if (finalMapStock == null) {
                    skuEsModel.setHasStock(false);
                }else {
                    skuEsModel.setHasStock(finalMapStock.get(skuEsModel.getSkuId()));
                }
                BrandEntity brandEntity = brandDao.selectById(skuEsModel.getBrandId());
                skuEsModel.setBrandName(brandEntity.getName());
                skuEsModel.setBrandImg(brandEntity.getLogo());

                CategoryEntity categoryEntity = categoryDao.selectById(skuEsModel.getCatalogId());
                skuEsModel.setCatalogName(categoryEntity.getName());
                // 设置 attrs
                skuEsModel.setAttrs(collect2);
                return skuEsModel;
            }).collect(Collectors.toList());
            // 3. 设置进 es, 调用 gulimall-search 的服务
            R r = searchFeignService.saveSkuProducts(collect);
            if (r.getCode() == 0) {
               // 成功
                SpuInfoEntity spuInfoEntity = new SpuInfoEntity();
                // 上架状态
                spuInfoEntity.setPublishStatus(1);
                UpdateWrapper<SpuInfoEntity> wrapper = new UpdateWrapper<SpuInfoEntity>().eq("id", spuId);
                this.update(spuInfoEntity,wrapper);
            }else {
                // 失败
                // TODO 商品上架失败问题?  重复调用 接口幂等性 重试机制
            }
        }


    }

    @Override
    public SpuInfoEntity getSpuInfoBySkuId(Long id) {
        SkuInfoEntity skuInfo = skuInfoDao.selectById(id);
        Long spuId = skuInfo.getSpuId();
        SpuInfoEntity byId = this.getById(spuId);
        return byId;
    }

}